source('sourced_script/model_fourier.R')
source('sourced_script/helper_functions.R')
source('sourced_script/plot_fn.R')

library(trelliscopejs)
library(plotly)
library(lme4)
library(tidyverse)
library(lubridate)
library(chron)

Read in our data and take a look:

model_df <- read.csv('data/plotting_df.csv', check.names = FALSE, stringsAsFactors = FALSE)
head(model_df, 10)
# there two commands are the same
# model_df %>% mutate(hours_copy = hours)
# mutate(model_df, hours_copy = hours)

# mutate, select, filter
# ...

Add columns to the data

Words: Make 7 new columns:

model_df <- model_df %>%
  mutate(t_awake = ifelse(DayNight == 'day', 
                          yes = ifelse(hours <= 24 & hours >= 6, hours - 6, 18 + hours),
                          no = ifelse(hours <= 24 & hours >= 18, hours - 18, 6 + hours))) %>%
  mutate(cost24 = cos(2*pi*hours/24), sint24 = sin(2*pi*hours/24),
         cost12 = cos(2*pi*hours/12), sint12 = sin(2*pi*hours/12),
         cost8 = cos(2*pi*hours/8), sint8 = sin(2*pi*hours/8))

model_df %>% head()

Nest the data for each lipid

Words:

Take model_df, group rows by identical values in the column ‘Lipid’, then bundle up all the data in each group. This results in a new column called ‘data’ where every element is an entire dataframe.

model_df <- model_df %>% 
  group_by(Lipid) %>% 
  nest()

head(model_df)

Apply a linear model to each data subset

Words:

Take model_df, make two new columns called slope and params. Each row of slope/params are the result of applying the functions get_slope/model_fs to the value of data in the same row.

df <- model_df$data[[1]]

get_slope <- function(df){
  res <- lm(Value ~ hours, data = df)
  res$coefficients[2]
}

get_slope(df)
     hours 
-0.1379347 
model_df_params <- model_df %>%
  mutate(slope = map(data, get_slope),
         params = map(data, model_fs))

Lets make a simple plot function and apply it to one element of that ‘data’ column we made.

simple_plot <- function(df){
  ggplot(df, aes(x = hours, y = Value, color = DayNight)) + geom_point()
}

simple_plot(df)

A more complicated plot that takes both the data and params columns we made

# try plotting one
df <- model_df_params$data[[1]]
params <- model_df_params$params[[1]]
lipidplot_nfits_facet(df, params, subjects_day = TRUE, subjects_night = FALSE, fit_day_24 = TRUE, fit_night_24 = FALSE)

Apply our plotting function to the data for every lipid:

We make use of the map_plot, and pmap_plot functions within a mutate call. These both work like map(), in that the first argument is a list of arguments that will be passed to a plot function, and the second argument is the name of the plot function.

# for axes labels
cats = c("1:30", "4:30",  "7:30", "10:30", "13:30", "16:30", "22:30")

# fancy plots, takes a big ol list of parameters and passes it to a function called lipidplot_nfits_facet()
facet_plots <- model_df_params %>%
  mutate(plot = pmap_plot(list(df = data, params = params, subjects_day = TRUE, subjects_night = FALSE, fit_day_24 = TRUE, fit_night_24 = FALSE,
                               cats = list(cats), period = list(c(24,12,8))), 
                          lipidplot_nfits_facet)) 

# our simple plot function applied to each element of the 'data' column.
simple_plots <- model_df_params %>% 
  mutate(plot = map_plot(data, simple_plot))

# (Optional) add cognostics for trelliscope using mutate and a chain of functions that 'unnests' the 'params' column
facet_plots_cogs <- facet_plots %>% 
  mutate(Lipid = cog(Lipid, desc = "Lipid Identifier", default_label = T)) %>%
  cbind(do.call(rbind.data.frame, facet_plots$params) %>% mutate_each(cog))

simple_plots_cogs <- simple_plots %>%
  mutate(Lipid = cog(Lipid, desc = "Lipid Identifier", default_label = T), 
         slope = cog(unlist(slope), desc = 'the slope of course'))
facet_plots_cogs %>% trelliscope(name = 'Plots of all lipids', nrow = 1, ncol = 1, path = 'displays/', thumb = TRUE, width = 1000, desc = 'Plots of all lipids')
simple_plots_cogs %>% trelliscope(name = 'simple plots', nrow = 1, ncol = 1, path = 'displays/', thumb = TRUE, width = 800, desc = 'Some simple plots')